package com.azunitech.apm.bundles.admin;

import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;



public class CharacterEncodingFilter implements Filter {
	private String encoding = "UTF-8";  
	private Boolean forceEncoding = true;  
	
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	public void doFilter(ServletRequest request, ServletResponse response,  FilterChain chain) throws IOException, ServletException {  
		  ExtraParamWrappedRequest reqwrapper = new ExtraParamWrappedRequest((HttpServletRequest) request, null);  
		  
		  if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {  
		   Map additionalParams = new HashMap();  
		   additionalParams.put("_charset_", new String[]{encoding});  
		   reqwrapper = new ExtraParamWrappedRequest((HttpServletRequest) request, additionalParams);  
		   reqwrapper.setCharacterEncoding(this.encoding);  
		  
		   if (this.forceEncoding) {  
		    response.setCharacterEncoding(this.encoding);  
		   }  
		  
		  }  
		  
		  chain.doFilter(reqwrapper, response);  
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		try {  
			String encoding = filterConfig.getInitParameter("init.charencoding.filter.encoding");  
			if(encoding != null && encoding.trim().length() >0) {  
				this.encoding = encoding;  
			}  
			  
			if(filterConfig.getInitParameter("init.charencoding.filter.forceencoding") != null) {  
				Boolean forceEncoding = Boolean.parseBoolean(filterConfig.getInitParameter("init.charencoding.filter.forceencoding"));  
				this.forceEncoding = forceEncoding;  
			}  
		} 
		catch (Exception ex) {  
			ex.printStackTrace();  
		}  
	}  
	
	class ExtraParamWrappedRequest extends HttpServletRequestWrapper {  
		private final Map modifiableParameters;  
		private Map allParameters = null;  
		  
		public ExtraParamWrappedRequest(final HttpServletRequest request, final Map additionalParams) {  
			super(request);  
			modifiableParameters = new TreeMap();  
		  
			if(additionalParams != null) {  
				modifiableParameters.putAll(additionalParams);  
			}  
		  
	  	}  
		  
		@Override  
		public String getParameter(final String name) {  
			String strings = getRequest().getParameter(name);  
		  
			if (strings != null){  
				return strings;  
			}  
			return null;  
	  	}  
		  
		@SuppressWarnings("unchecked")  
		@Override  
		public Map getParameterMap() {  
			if (allParameters == null) {  
				allParameters = new TreeMap();  
				allParameters.putAll(super.getParameterMap());  
				allParameters.putAll(modifiableParameters);  
			}  
			return Collections.unmodifiableMap(allParameters);  
		}  
		  
		@Override  
		public Enumeration getParameterNames() {  
			return Collections.enumeration(getParameterMap().keySet());  
		}  
	}  	
}